package com.googlecode.klenwell.playndev.core;

import static playn.core.PlayN.graphics;

import org.jbox2d.common.Vec2;

import com.googlecode.klenwell.playndev.core.event.EventListener;
import com.googlecode.klenwell.playndev.core.event.GameEvent;

import playn.core.Canvas;
import playn.core.CanvasImage;
import playn.core.Color;
import playn.core.ImageLayer;

public class Circle implements EventListener {

	Vec2 pt = new Vec2(0, 0);
	int radius = 0;
	int color = 0;
	float alpha = 1.0f;
    public boolean isBeingDragged = false;

	public Circle(int x, int y, int radius, int color, float alpha) {
		pt = new Vec2(x, y);
		this.radius = radius;
		this.color = color;
		this.alpha = alpha;
	}

	public CanvasImage asCanvasImage() {
		int diameter = radius * 2;
		CanvasImage circleImage = graphics().createImage(diameter, diameter);
		Canvas canvas = circleImage.canvas();
		canvas.setFillColor(color);
		canvas.fillCircle((float) radius, (float) radius, (float) radius);
		canvas.setAlpha(alpha);
		
		float strokeWidth = 16.0f;
		canvas.setStrokeColor(Color.rgb(255, 255, 255));
        canvas.setStrokeWidth(strokeWidth);
        canvas.strokeCircle((float) radius, (float) radius, (float) radius - (strokeWidth / 2.0f));
        
		return circleImage;
	}

	public ImageLayer asImageLayer() {
	    // NOTE: use this for transparent images
		CanvasImage image = asCanvasImage();
		ImageLayer imageLayer = graphics().createImageLayer(image);
		imageLayer.setAlpha(alpha);
		imageLayer.transform().translate(getScreenX(), getScreenY());
		return imageLayer;
	}

	public float getScreenX() {
		int screenX = GraphicsApi.worldToScreenX((int) Math.round(pt.x));
		return screenX - radius;
	}

	public float getScreenY() {
		int screenY = GraphicsApi.worldToScreenY((int) Math.round(pt.y));
		return screenY - radius;
	}

    @Override
    public void processBoundEvent(GameEvent event) {
        if (event.binding.key == "hitCheck") {
            hitCheck(event);
        } else if (event.binding.key == "pointerEnd") {
            pointerEnd(event);
        } else if (event.binding.key == "beingDragged") {
            beingDragged(event);
        }
        
    }

    private void beingDragged(GameEvent event) {
        if ( isBeingDragged ) {
            pt = event.pt;
        }
    }

    private void pointerEnd(GameEvent event) {
        if ( isBeingDragged ) {
            isBeingDragged = false;
            System.out.println("stop dragging " + toString());
        }
    }

    private void hitCheck(GameEvent event) {
        if ( contains(event.pt) ) {
            System.out.println("now dragging " + toString() + " hit at pt " + event.pt);
            isBeingDragged = true;
        }
        else {
            System.out.println(toString() + " miss at pt: " + event.pt);
            isBeingDragged = false;
        }
        
    }

    private boolean contains(Vec2 pt2) {
        Float cx = pt.x;
        Float cy = pt.y;
        Float px = pt2.x;
        Float py = pt2.y;
        Double squareDist = Math.pow(cx - px, 2) + Math.pow(cy - py, 2);
        return squareDist <= Math.pow(radius, 2);
    }

}
